yolov4(darknet官方)用于检测垃圾和分类

您所在的位置:网站首页 yolov4 github yolov4(darknet官方)用于检测垃圾和分类

yolov4(darknet官方)用于检测垃圾和分类

2023-03-22 20:43| 来源: 网络整理| 查看: 265

前段时间做了华为云的垃圾检测分类比赛(垃圾分类检测),当时的方案是SSD+efficientdet+CiouLoss,很遗憾最终未能进入复赛(如果大家感兴趣,也可以去比赛官方页面下载来玩一玩)。这几天闲来无事玩了下darknet官方版的yolov4和ultralytics的yolov5。嗯,初步测试yolov4-tiny确实很不错,而且速度是真的快。本篇文章主要记录如何正确食用yolov4,下一次记录下yolov5的使用。主要分为darknet编译,数据准备,训练,验证....。其实官方文档写的是真的详细,这里提取重要信息。yolov4地址:

编译darknet

darknet一般有两个含义,一个指的是类似resnet,vgg之类的yolo用的特征提取主干网络,还有一个就是用c语言编写的一个深度学习框架,虽然没有tf,torch功能这么多,但简单高效。官方的yolo实现就是这样实现,完全不依赖于其它任何框架,速度又快移植性又好。这里就当做正常的c语言项目来编译就好,以ubuntu系统为例:如果需要可视化图片,需要安装opencv,如果需要GPU加速训练,需要提安装cuda,cudnn等

git clone [email protected]:AlexeyAB/darknet.git cd darknet gedit Makefile ''' GPU=1#是否需要gpu,如果没有卡就设置为0吧 CUDNN=1#同上 CUDNN_HALF=0 OPENCV=0#如果没有安装opencv,或者设置为1编译报错,这里设置为0 ''' make -j8#编译

这样如果编译成功,会在当前路径下生成可执行darknet文件.然后会有一个build目录(编译产生的各种结果都在里面,而且我后面的训练数据权重上面的都在build下面,因美味这样把源码隔开了,有好处。官方教程中也建议把制作好的数据集也放到里面),为了简单的测试一下,先下载好yolov4训练好的权重(看readme)。然找个目录放好。在终端执行:

./darknet detector test cfg/coco.data yolov4.cfg yolov4.weights -ext_output data/dog.jpg

如果成功,会输出结果并且可视化图片会保存到当前路径下.

训练自己的数据

制作自己的配置文件(yolov4-tiny为例)

这个其实官方文档写得也很清楚,有的细节需要补充强调下.

看这上面写这么多,其实如果有稍微了解过yolo系列的就应该清楚是怎么一回事。yolo的各个版本的网络结构,参数配置都是写到cfg/下面的xxx.cfg里面的。主干网络的最后一层输出通道为(classes + 5)x3.譬如你打开原始的cfg文件(针对coco数据),那么看到的最后一层的输出肯定是255,因为coco有80类,(80+5)x3=255.这么来的,以我自己的垃圾数据为例,总共44类,因此(44+5)*3=147.以yolov4-tiny为例:更改cfg/yolov4-tiny.cfg

注意,其实这里的anchor最好也根据自己的数据集进行调整(就是聚类得到9个anchor),官方有实现,一行命令得到这个后面会讲到。为了方便,我把这个.cgf改名为了yolov4-tiny-garbage.cfg

制作数据集

这个是关键,我们拿到的目标检测数据往往是两种格式:coco或者voc,而yolo系列其实是有自己的专用组织格式。train.txt里面存储了所有的训练图片路径,每一行是一张。每一张图片的标注由一个.txt来存储,格式如下:

所以一般来讲需要自己写一个脚本将coco,voc或者其它格式的数据标注转换为yolo所需格式。关于如何转换数据,其实这个自己写一个简单的脚本并不复杂,如果嫌麻烦,网上搜索吧。我在这里也给出voc转yolo的代码。官方在这里建议在编译产生的build目录下存放训练数据build/darknet/x64/data

这里是我组织好的训练数据格式:图片和标注都放在garbage_images下面

voc_yolo.py

下面是我自己的voc格式数据转yolo格式的脚本,不同数据稍作修改可用

import xml.etree.ElementTree as ET import os import cv2 classes = ['一次性快餐盒','书籍纸张','充电宝', '剩饭剩菜' ,'包','垃圾桶','塑料器皿','塑料玩具','塑料衣架', '大骨头','干电池','快递纸袋','插头电线','旧衣服','易拉罐', '枕头','果皮果肉','毛绒玩具','污损塑料','污损用纸','洗护用品', '烟蒂','牙签','玻璃器皿','砧板','筷子','纸盒纸箱','花盆', '茶叶渣','菜帮菜叶','蛋壳','调料瓶','软膏','过期药物', '酒瓶','金属厨具','金属器皿','金属食品罐','锅','陶瓷器皿', '鞋','食用油桶','饮料瓶','鱼骨'] def convert_annotation(image_id): in_file = open('/home/admins/qyl/trash_detection/efficientnet_SSD/datasets/VOC2007/Annotations/%s.xml' % image_id) if not os.path.exists('./data/custom/labels1/'): os.makedirs('./data/custom/labels1/') out_file_img = open('./data/custom/trainval.txt', 'a') # 生成txt格式文件 out_file_label = open('./data/custom/labels1/%s.txt' % image_id,'a') # 生成txt格式文件 tree = ET.parse(in_file) root = tree.getroot() size = root.find('size') voc_img_dir='/home/admins/qyl/trash_detection/efficientnet_SSD/datasets/VOC2007/JPEGImages/{}.jpg'.format(image_id) out_file_img.write(voc_img_dir) out_file_img.write("\n") img=cv2.imread(voc_img_dir) dh = 1. / img.shape[0] dw = 1. / img.shape[1] cnt=len(root.findall('object')) if cnt==0: print('nulll null null.....') print(image_id) cc=0 for obj in root.iter('object'): cc+=1 cls = obj.find('name').text if cls not in classes: continue cls_id = classes.index(cls) xmlbox = obj.find('bndbox') if dw*float(xmlbox.find('xmin').text)

制作.data和.name文件

我们的程序是通过.data里面给定的train和val路径去寻找训练和验证数据集的。比如我自己的垃圾检测.data就像下面这样:

.name像这样

存储每一类对应的真实名字.

这样就制作好了数据集,至于上面的各种路径,其实没有那么死板,只要你自己的程序可以找到就行,以我自己的组织方式为例:

我把可执行的darknet文件也复制了一份到build/darknet/x64/下面

训练

最好先下载v4-tiny的预训练权重yolov4-tiny.conv.29;参看readme有下载路径不需要梯子,迅雷可以加速下载

./darknet detector train data/garbage.data cfg/yolov4-tiny-garbage.cfg ../../../weights/yolov4-tiny.conv.29 -map

注意,上面的路径很灵活,只要注意一点就是相对于./darknet可执行程序要能找到,比如我把darknet可执行程序放到了build/darknet/x64/下面,只需要在build/darknet/x64/执行上面的命令即可训练;

cfg/yolov4-tiny-garbage.cfg是制作的垃圾检测的.cfg文件;

../../../weights/yolov4-tiny.conv.29是我的预训练权重相对于当前目录的保存的位置

-map是采取边训练边验证map值的策略

还有训练的各种参数可以在.cfg文件里面设置

训练完的模型被保存在backup文件夹下

验证

如果训练的时候没有采取边训练边验证的方式。而是训练完了再验证,可以使用命令:

./darknet detector map data/garbage.data cfg/yolov4-tiny-garbage.cfg backup/yolov4-tiny-garbage_best.weights

建议这样验证一次,因为这样可以输出各个类别的详细map值

关于anchor聚类

下面说一下anchor的聚类问题,为了得到更好的训练效果,最好通过聚类得到自己数据集的anchor聚类中心。这里其实官方已经制作好了,只需要一个简单的命令就可以搞定。

./darknet detector calc_anchors data/garbage.data -num_of_clusters 9 -width 416 -height 416

输入图片尺寸为416x416,聚类数为9,通过garbage.data指定的路径去找到训练数据。

最后

关于darknet的使用其实还有很多,可查看官方readme;yolov4-tiny是真的名不虚传,真的快!而且也map也蛮不错

下一篇讲一讲yolov5的使用(仿佛大家更愿称其为最强pytorch版yolov4??)



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3